/**
 * 维护小程序库（用于聊天时发送）
 */
import { getLogger, Service } from '@gnlab/utils'
import { MemSubject } from '@gnlab/utils/rx'
import pick from 'lodash/pick'
import type { Services } from '@/services'
import { API } from '@/services/common/api'
import { type MiniProgramWord } from '@/services/common/definition/word'

const logger = getLogger('services/resources/mini-programs')

export type MiniProgram = Omit<MiniProgramWord, 'type'>

// 已保存到“小程序库”里的小程序，会额外获得 id 并指定类型
export interface SavedMiniProgram extends MiniProgram {
  id: number
  type: MiniProgramType // 0: 全员小程序    1: 我的小程序
}

export enum MiniProgramType {
  Global = 0, // 全员小程序
  Personal = 1, // 我的小程序
}

export class MiniPrograms extends Service<Services> {
  private get auth() {
    return this.services.auth
  }

  registered() {
    void this.auth.accountId.then(() => {
      void this.load()
    })
  }

  private readonly _list = new MemSubject<SavedMiniProgram[]>([])
  list = this._list.asStream()

  async load() {
    const resp = await API<SavedMiniProgram[]>('/MiniProgram/GetMiniPrograms')
    if (resp.success) {
      this._list.next(resp.data)
    } else {
      logger.warn('小程序列表加载失败', resp.error)
    }
  }

  async add(type: MiniProgramType, mp: MiniProgram) {
    const reqMiniProgram = {
      ...pick(mp, 'username', 'appid', 'appname', 'appicon', 'title', 'page_path', 'cover_path'),
      type,
    }
    const resp = await API('/MiniProgram/AddMiniProgram', { data: reqMiniProgram, formatter() {} })
    if (resp.success) {
      void this.load()
    } else {
      const typeName = type === MiniProgramType.Global ? '全员' : '个人'
      logger.warn(`${typeName}小程序添加失败：${resp.error}`)
    }
    return resp
  }

  async remove(id: number) {
    const resp = await API('/MiniProgram/RemoveMiniProgram', { data: { id }, formatter() {} })
    if (resp.success) void this.load()
    else logger.warn(`小程序删除失败：${resp.error}`)
    return resp
  }
}
